/*******************************************************************************
 * Copyright (c) 2014 Francesco Gabbrielli.
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Francesco Gabbrielli - initial API and implementation
 ******************************************************************************/
package it.francescogabbrielli.android.solidalapp.file;

import java.util.ArrayList;

import it.francescogabbrielli.android.solidalapp.BaseFragment;
import it.francescogabbrielli.android.solidalapp.ChatMessage;
import it.francescogabbrielli.android.solidalapp.DataEvent;
import it.francescogabbrielli.android.solidalapp.R;
import it.francescogabbrielli.android.solidalapp.SolidalApp;
import it.francescogabbrielli.android.solidalapp.SolidalApp.DataKey;
import it.francescogabbrielli.android.solidalapp.StatusEvent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.RingtoneManager;
import android.media.ToneGenerator;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;

/**
 * Simple in memory chat
 */
public class ChatFragment extends BaseFragment<FileFragmentListener> 
			implements OnEditorActionListener, OnItemClickListener {
	
	private ChatAdapter adapter;
	
	private MediaPlayer mediaPlayer; 
	
	class ChatAdapter extends BaseAdapter {
		
		ArrayList<ChatMessage> list;
		
		public ChatAdapter() {
			list = new ArrayList<ChatMessage>();
		}
				
		public ArrayList<ChatMessage> getList() {
			return list;
		}
		
		public void setList(ArrayList<ChatMessage> list) {
			this.list = list;
			notifyDataSetChanged();
		}
		
		public void add(ChatMessage m) {
			list.add(m);
			notifyDataSetChanged();
		}
		
		@Override
		public int getCount() {
			return list.size();
		}

		@Override
		public Object getItem(int position) {
			return list.get(position);
		}

		@Override
		public long getItemId(int position) {
			return list.get(position).id;
		}
		
		public ChatMessage getItemById(long id) {
			int pos = getPositionById(id);
			if (pos>=0)
				return list.get(pos);
			else
				return null;
		}
		
		public int getPositionById(long id) {
			for (int i=0; i<list.size(); i++)
				if (list.get(i).id == id)
					return i;
			return -1;
		}
		
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			
			if (convertView == null) {
				
				TextView tv = new TextView(getActivity());
				ChatMessage m = list.get(position);
				tv.setId(position);
				tv.setText(m.text);
				
				switch (m.type) {
				case SENDING:
					tv.setTextColor(getResources().getColor(R.color.chat_message_sending));
					tv.setGravity(Gravity.RIGHT);
					break;
				case SENT:
					tv.setTextColor(getResources().getColor(R.color.chat_message_sent));
					tv.setGravity(Gravity.RIGHT);
					break;
				case ERROR:
					tv.setTextColor(getResources().getColor(R.color.chat_message_error));
					tv.setGravity(Gravity.RIGHT);
					break;
				case INCOMING:
					tv.setTextColor(getResources().getColor(R.color.chat_message_incoming));
					tv.setGravity(Gravity.LEFT);
					break;
				}
				
				convertView = tv;
			}
			
			return convertView;
		}

	}
	
	public ChatFragment() {}
	
	private DataKey chatKey;
	
	@Override
	public void onStatusUpdate(StatusEvent event) {
		
	}
	
	@Override
	public void onDataChanged(DataEvent event) {
		
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		
		mediaPlayer = MediaPlayer.create(getActivity(), RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
		
		View view = inflater.inflate(R.layout.fragment_chat, container, false);
		
		EditText e = (EditText) view.findViewById(R.id.chat_edit);
		e.setOnEditorActionListener(this);
		
		ListView list = (ListView) view.findViewById(R.id.chat_container);
		list.setOnItemClickListener(this);
		if (adapter==null)
			adapter = new ChatAdapter();
		list.setAdapter(adapter);
		
		return view;
	}
	
	@Override
	public void onViewStateRestored(Bundle savedInstanceState) {
		super.onViewStateRestored(savedInstanceState);
		FileActivity<?> fa = (FileActivity<?>) getActivity();
		chatKey = fa.getChatKey();
		//		if (savedInstanceState!=null) {
			@SuppressWarnings("unchecked")
//			ArrayList<ChatMessage> l = (ArrayList<ChatMessage>) savedInstanceState.getSerializable("chat");
			ArrayList<ChatMessage> l = (ArrayList<ChatMessage>) app.getData(chatKey);
			if (l!=null)
				adapter.setList(l);
//		}
			
		// execute queued actions

		fa.execChatQueue(this);
	}
			
	@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		if (!adapter.getList().isEmpty())
			app.setData(chatKey, adapter.getList());
//			outState.putSerializable("chat", adapter.getList());
	}
	
	@Override
	public void onDestroy() {
		if (!adapter.getList().isEmpty())
			app.setData(chatKey, adapter.getList());
		super.onDestroy();
	}
		
	@Override
	public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
		if (actionId == EditorInfo.IME_ACTION_SEND) {
			String msg = String.valueOf(v.getText());
			if (!"".equals(msg)) {
				long id = System.currentTimeMillis();
				adapter.add(new ChatMessage(id, msg, ChatMessage.Type.SENDING));
				interactionListener.sendMessage(id, msg);
				v.setText("");
				v.requestFocus();
			}
		}
		return false;
	}
	
	public void onMessageSent(long id, String error) {
		try {
			if (id>0) {
				int pos = adapter.getPositionById(id);
				ChatMessage cm = (ChatMessage) adapter.getItem(pos);
				ListView lv = (ListView) getView().findViewById(R.id.chat_container);
				TextView tv = (TextView) lv.getChildAt(pos);
				if (error==null) {
					tv.setTextColor(getResources().getColor(R.color.chat_message_sent));
					cm.type = ChatMessage.Type.SENT;
				} else {
					app.alert(R.string.error_chat_send);
					tv.setTextColor(getResources().getColor(R.color.chat_message_error));
					cm.type = ChatMessage.Type.ERROR;
				}
			}
		} catch(Exception e) {
			Log.w(SolidalApp.TAG, "Cannot set chat index sent: "+id, e);
		}
	}
	
	public void onMessageReceived(String message, boolean isNotification) {
		@SuppressWarnings("unchecked")
		ArrayList<ChatMessage> l = (ArrayList<ChatMessage>) app.getData(chatKey);
		if (l!=null) {
			// merge current
			if (adapter.getList()!=l) {
				l.addAll(0, adapter.getList());
				adapter.setList(l);
			} else
				adapter.notifyDataSetChanged();
		}
		if (!isNotification)
			mediaPlayer.start();
	}

	@Override
	public void onItemClick(AdapterView<?> listView, View itemView, int position, long id) {
		ChatMessage m = (ChatMessage) adapter.getItem(position);
		if (m.type==ChatMessage.Type.ERROR) {
			ListView lv = (ListView) getView().findViewById(R.id.chat_container);
			TextView tv = (TextView) lv.getChildAt((int) id-1);
			interactionListener.sendMessage(id, m.text);
		}
	}
	
}
